package base

import (
	"bytes"
	"crypto/md5"
	"encoding/base64"
	"errors"
	"io"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
)

type H2oClaims struct {
	Username string `json:"username"`
	OpenId   string `json:"openid"`
	Randomid string `json:"randomid"`
	jwt.RegisteredClaims
}

func GetToken(usename string, uid string, role string) (string, error) {
	cure := time.Now()
	c := H2oClaims{
		usename,
		uid,
		jwt.TimePrecision.String(),
		jwt.RegisteredClaims{
			Issuer:    "Access",
			Subject:   role,
			Audience:  []string{"H2oT"},
			ID:        uid,
			ExpiresAt: jwt.NewNumericDate(cure.Add(7 * 24 * time.Hour)),
			IssuedAt:  jwt.NewNumericDate(cure),
			NotBefore: jwt.NewNumericDate(cure),
		},
	}

	toekn := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	ss, err := toekn.SignedString([]byte(GConf.Http.Jwt))
	if err != nil {
		GLogger.Infof("Get token error:%s", err.Error())
		return "", err
	}
	return ss, nil
}

func VerifyToken(tokenString string, c *gin.Context) error {
	token, err := jwt.ParseWithClaims(tokenString, &H2oClaims{}, func(t *jwt.Token) (interface{}, error) {
		return []byte(GConf.Http.Jwt), nil
	})
	if err != nil {
		GHBase.Logger.Infof("Parse token error:%s", err.Error())
		return err
	}

	claims, ok := token.Claims.(*H2oClaims)
	if !ok {
		GLogger.Infof("Parse token error: type error")
		return errors.New("type error")
	}
	c.Set(HEAD_USER_ID, claims.OpenId)
	c.Set(HEAD_USER_NAME, claims.Username)
	c.Set(HEAD_USER_ROLE, claims.Subject)
	return nil

}

func MD5Sign(ts string, content string, sault string) string {
	wr := md5.New()
	buff := bytes.Buffer{}
	buff.WriteString(sault)
	buff.WriteString(ts)
	buff.WriteString(content)
	io.WriteString(wr, buff.String())
	sign := base64.StdEncoding.EncodeToString(wr.Sum(nil))
	return sign
}
